import { BaseEntity } from '../domain/entities/BaseEntity';
import { Task } from '../domain/entities/Task';
import { Player } from '../domain/entities/Player';
import { ModernBaseService } from '../service/base/ModernBaseService';
import { 
    TaskType, 
    TaskStatus, 
    TaskTargetType, 
    TaskConfig, 
    TaskTarget, 
    TaskReward, 
    PlayerTaskProgress, 
    ServerTaskProgress,
    TaskSystemData,
    RankingData
} from '../core/rpg/types/task';
import { ComType } from '../core/tool/component';
import { config, configKey } from '../config';

/**
 * 任务数据访问层
 * 职责：
 * 1. 任务数据的持久化
 * 2. 玩家任务进度管理
 * 3. 全服任务统计
 * 4. 排行榜数据管理
 * 5. 世界任务数据管理
 */
export class TaskRepository extends ModernBaseService {
    private playerTaskCache = new Map<string, CachedTaskData>();
    private serverTaskCache = new Map<string, ServerTaskData>();
    private readonly CACHE_TTL = 300000; // 5分钟缓存

    // 全服任务邮件发送状态跟踪
    private serverTaskMailSent = new Set<string>();

    /**
     * 获取玩家任务数据
     * @param playerId 玩家ID
     * @returns 任务数据
     */
    async getPlayerTaskData(playerId: string): Promise<PlayerTaskData> {
        return this.cached(`task_${playerId}`, async () => {
            this.validateRequiredParams({ playerId }, ['playerId']);

            const player = this.sdk.getPlayerById(playerId);
            if (!player) {
                throw new Error(`Player ${playerId} not found`);
            }

            // 从玩家组件获取任务数据
            const taskComponent = player.getComponent('task');
            if (!taskComponent) {
                // 如果没有任务组件，创建默认数据
                return this.createDefaultTaskData(playerId);
            }

            // 转换为标准格式
            const taskData: PlayerTaskData = {
                playerId,
                playerTasks: this.convertPlayerTasksToEntities(taskComponent.taskData?.playerTasks || []),
                serverTasks: this.convertServerTasksToEntities(taskComponent.taskData?.serverTasks || []),
                worldTasks: this.convertWorldTasksToEntities(taskComponent.taskData?.worldTasks || []),
                completedTaskIds: taskComponent.taskData?.completedTaskIds || [],
                totalCompletedTasks: taskComponent.taskData?.totalCompletedTasks || 0,
                lastUpdateTime: taskComponent.taskData?.lastUpdateTime || Date.now(),
                lastUpdated: new Date()
            };

            return taskData;
        }, this.CACHE_TTL);
    }

    /**
     * 保存玩家任务数据
     * @param playerId 玩家ID
     * @param taskData 任务数据
     */
    async savePlayerTaskData(playerId: string, taskData: PlayerTaskData): Promise<void> {
        await this.safeExecute(async () => {
            this.validateRequiredParams({ playerId, taskData }, ['playerId', 'taskData']);

            const player = this.sdk.getPlayerById(playerId);
            if (!player) {
                throw new Error(`Player ${playerId} not found`);
            }

            // 获取任务组件
            let taskComponent = player.getComponent('task');
            if (!taskComponent) {
                taskComponent = player.addComponent('task');
            }

            // 转换Entity为原始格式并保存
            taskComponent.taskData = {
                playerTasks: this.convertEntitiesToPlayerTasks(taskData.playerTasks),
                serverTasks: this.convertEntitiesToServerTasks(taskData.serverTasks),
                worldTasks: this.convertEntitiesToWorldTasks(taskData.worldTasks),
                completedTaskIds: taskData.completedTaskIds,
                totalCompletedTasks: taskData.totalCompletedTasks,
                lastUpdateTime: taskData.lastUpdateTime
            };

            // 更新缓存
            this.updateCache(playerId, taskData);

            this.log(`Task data saved for player ${playerId}, tasks: ${taskData.playerTasks.length}`);
        }, 'savePlayerTaskData');
    }

    /**
     * 获取任务配置
     * @returns 任务配置列表
     */
    async getTaskConfigs(): Promise<TaskConfig[]> {
        return this.cached('task_configs', async () => {
            try {
                const taskConfigs = config.get(configKey.配置_常规任务) as Map<string, any>;
                const configs: TaskConfig[] = [];
                
                taskConfigs.forEach((config: any, key: string) => {
                    const targets = config.targets.map((target: any) => ({
                        type: target.type,
                        count: Number(target.count),
                        current: 0,
                        description: target.description
                    }));
                    
                    const rewards = config.rewards.map((reward: any) => ({
                        type: reward.type,
                        id: reward.id,
                        count: Number(reward.count),
                        name: reward.name
                    }));
                    
                    configs.push({
                        id: key,
                        name: config.name,
                        description: config.description,
                        type: config.type,
                        targets: targets || [],
                        rewards: rewards || [],
                        startTime: 0,
                        endTime: 0,
                        duration: Number(config.duration)
                    });
                });

                return configs;
            } catch (error) {
                this.log('Failed to load task configs: ' + (error as any).message, 'error');
                return [];
            }
        }, 3600000); // 缓存1小时
    }

    /**
     * 获取玩家世界任务
     * @param playerId 玩家ID
     * @param mapName 地图名称
     * @returns 世界任务列表
     */
    async getPlayerWorldTasks(playerId: string, mapName: string): Promise<TaskConfig[]> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, mapName }, ['playerId', 'mapName']);

            // 先检查是否已有该地图的世界任务
            const existingWorldTasks = this.sdk.worldTask.getWorldTasks(mapName);
            
            // 过滤出属于当前玩家的世界任务
            const playerWorldTasks = existingWorldTasks.filter((task: any) => 
                task.id.includes(playerId)
            );
            
            // 检查现有任务是否符合新格式
            if (playerWorldTasks.length > 0) {
                const validWorldTask = playerWorldTasks.find((task: any) => 
                    task.id.startsWith('world_task_') && task.targets.length >= 1
                );
                
                if (validWorldTask) {
                    return [validWorldTask];
                } else {
                    // 清理旧格式任务并重新生成
                    await this.clearPlayerWorldTasks(playerId);
                }
            }
            
            // 生成新的世界任务
            const newWorldTasks = await this.sdk.worldTask.generateWorldTasks(mapName, playerId);
            return newWorldTasks;
        }, 'getPlayerWorldTasks');
    }

    /**
     * 清理玩家世界任务
     * @param playerId 玩家ID
     * @returns 清理结果
     */
    async clearPlayerWorldTasks(playerId: string): Promise<void> {
        await this.safeExecute(async () => {
            this.validateRequiredParams({ playerId }, ['playerId']);

            // 清理WorldTaskManage中的数据
            await this.sdk.worldTask.clearPlayerWorldTasks(playerId);
            
            // 清除相关缓存
            this.clearCache(`task_${playerId}`);
            
            this.log(`Cleared world tasks for player ${playerId}`);
        }, 'clearPlayerWorldTasks');
    }

    /**
     * 更新任务进度
     * @param playerId 玩家ID
     * @param targetType 目标类型
     * @param targetId 目标ID
     * @param count 增加的数量
     * @returns 更新结果
     */
    async updateTaskProgress(
        playerId: string, 
        targetType: TaskTargetType, 
        targetId: string | undefined, 
        count: number = 1
    ): Promise<TaskProgressUpdateResult> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, targetType, count }, ['playerId', 'targetType', 'count']);

            const taskData = await this.getPlayerTaskData(playerId);
            const taskConfigs = await this.getTaskConfigs();
            const updatedTasks: Task[] = [];
            const completedTasks: Task[] = [];

            // 获取世界任务配置
            const player = this.sdk.getPlayerById(playerId);
            const posComponent = player?.getComponent(ComType.位置);
            const mapName = posComponent?.mapName || 'default';
            
            let worldTaskConfigs: TaskConfig[] = [];
            try {
                worldTaskConfigs = await this.getPlayerWorldTasks(playerId, mapName);
            } catch (error) {
                this.log(`Failed to get world tasks: ${(error as any).message}`, 'warn');
            }

            // 合并所有任务配置
            const allTaskConfigs = [...taskConfigs, ...worldTaskConfigs];

            // 更新常规任务和世界任务
            for (const taskConfig of allTaskConfigs) {
                const existingTask = taskData.playerTasks.find(t => t.id === taskConfig.id);
                
                if (!existingTask) {
                    // 创建新任务
                    const newTask = this.createTaskFromConfig(taskConfig);
                    taskData.playerTasks.push(newTask);
                }

                const task = taskData.playerTasks.find(t => t.id === taskConfig.id)!;
                
                // 检查任务目标是否匹配
                const matchingTargets = task.targets.filter(target => {
                    if (target.type !== targetType) return false;
                    if (targetId && target.description && !target.description.includes(targetId)) {
                        return false;
                    }
                    return true;
                });

                // 更新匹配的目标进度
                for (const target of matchingTargets) {
                    const currentProgress = target.current || 0;
                    if (currentProgress < target.count) {
                        const oldCurrent = currentProgress;
                        target.current = Math.min(currentProgress + count, target.count);
                        
                        if ((target.current || 0) > oldCurrent) {
                            updatedTasks.push(task);
                            
                            // 检查任务是否完成
                            if (this.isTaskCompleted(task) && task.status !== TaskStatus.已完成) {
                                task.status = TaskStatus.已完成;
                                (task as any).completedTime = Date.now();
                                completedTasks.push(task);
                                
                                // 更新统计
                                if (!taskData.completedTaskIds.includes(task.id)) {
                                    taskData.completedTaskIds.push(task.id);
                                    taskData.totalCompletedTasks++;
                                }
                            }
                        }
                    }
                }
            }

            // 更新全服任务进度
            await this.updateServerTaskProgress(targetType, targetId, count);

            // 保存更新后的数据
            taskData.lastUpdateTime = Date.now();
            taskData.lastUpdated = new Date();
            await this.savePlayerTaskData(playerId, taskData);

            return {
                success: true,
                message: '任务进度更新成功',
                updatedTasks,
                completedTasks
            };
        }, 'updateTaskProgress');
    }

    /**
     * 完成任务
     * @param playerId 玩家ID
     * @param taskId 任务ID
     * @returns 完成结果
     */
    async completeTask(playerId: string, taskId: string): Promise<TaskCompletionResult> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, taskId }, ['playerId', 'taskId']);

            const taskData = await this.getPlayerTaskData(playerId);
            const task = taskData.playerTasks.find(t => t.id === taskId);
            
            if (!task) {
                return {
                    success: false,
                    message: '任务不存在',
                    rewards: []
                };
            }

            if (task.status === TaskStatus.已完成) {
                return {
                    success: false,
                    message: '任务已完成',
                    rewards: []
                };
            }

            if (!this.isTaskCompleted(task)) {
                return {
                    success: false,
                    message: '任务未达成完成条件',
                    rewards: []
                };
            }

            // 标记任务为已完成
            task.status = TaskStatus.已完成;
            (task as any).completedTime = Date.now();
            
            // 更新统计
            if (!taskData.completedTaskIds.includes(taskId)) {
                taskData.completedTaskIds.push(taskId);
                taskData.totalCompletedTasks++;
            }

            // 获取任务奖励
            const rewards = await this.calculateTaskRewards(task);

            // 保存数据
            await this.savePlayerTaskData(playerId, taskData);

            return {
                success: true,
                message: '任务完成',
                task,
                rewards
            };
        }, 'completeTask');
    }

    /**
     * 获取全服任务统计
     * @param taskType 任务类型
     * @returns 统计数据
     */
    async getServerTaskStats(taskType?: TaskType): Promise<ServerTaskStats> {
        return this.cached(`server_task_stats_${taskType || 'all'}`, async () => {
            const allPlayers = this.sdk.getAllPlayers();
            const stats: ServerTaskStats = {
                totalPlayers: allPlayers.length,
                activePlayers: 0,
                totalTasksCompleted: 0,
                taskCompletionByType: {},
                averageTasksPerPlayer: 0,
                lastUpdated: new Date()
            };

            for (const player of allPlayers) {
                try {
                    const taskData = await this.getPlayerTaskData(player.id);
                    
                    if (taskData.playerTasks.length > 0) {
                        stats.activePlayers++;
                    }
                    
                    stats.totalTasksCompleted += taskData.totalCompletedTasks;
                    
                    // 统计按类型分组的任务完成情况
                    for (const task of taskData.playerTasks) {
                        if (task.status === TaskStatus.已完成) {
                            const type = task.type || 'unknown';
                            stats.taskCompletionByType[type] = (stats.taskCompletionByType[type] || 0) + 1;
                        }
                    }
                } catch (error) {
                    this.log(`Failed to get task data for player ${player.id}: ${(error as any).message}`, 'warn');
                }
            }

            stats.averageTasksPerPlayer = stats.activePlayers > 0 
                ? stats.totalTasksCompleted / stats.activePlayers 
                : 0;

            return stats;
        }, 600000); // 缓存10分钟
    }

    /**
     * 获取排行榜数据
     * @param type 排行榜类型
     * @param limit 限制数量
     * @returns 排行榜数据
     */
    async getRankingData(type: string, limit: number = 10): Promise<RankingData[]> {
        return this.cached(`ranking_${type}_${limit}`, async () => {
            const allPlayers = this.sdk.getAllPlayers();
            const rankings: RankingData[] = [];

            for (const player of allPlayers) {
                try {
                    const taskData = await this.getPlayerTaskData(player.id);
                    
                    rankings.push({
                        playerId: player.id,
                        playerName: player.name || player.id,
                        taskCompleted: taskData.totalCompletedTasks,
                        taskPoints: this.calculateRankingScore(taskData, type),
                        lastUpdateTime: Date.now(),
                        score: this.calculateRankingScore(taskData, type),
                        data: {
                            totalCompleted: taskData.totalCompletedTasks,
                            activeTasks: taskData.playerTasks.filter(t => t.status === TaskStatus.进行中).length
                        }
                    });
                } catch (error) {
                    this.log(`Failed to get ranking data for player ${player.id}: ${(error as any).message}`, 'warn');
                }
            }

            // 按分数排序
            rankings.sort((a, b) => (b.score || 0) - (a.score || 0));
            
            // 添加排名
            rankings.forEach((ranking, index) => {
                ranking.rank = index + 1;
            });

            return rankings.slice(0, limit);
        }, 300000); // 缓存5分钟
    }

    /**
     * 批量更新任务进度
     * @param playerId 玩家ID
     * @param updates 更新列表
     * @returns 批量更新结果
     */
    async batchUpdateTaskProgress(playerId: string, updates: TaskProgressUpdate[]): Promise<BatchTaskUpdateResult> {
        return this.batchProcess(updates, async (update, index) => {
            return await this.updateTaskProgress(playerId, update.targetType, update.targetId, update.count);
        }, 'batchUpdateTaskProgress');
    }

    /**
     * 检查邮件发送状态
     * @param taskId 任务ID
     * @returns 是否已发送
     */
    isMailSent(taskId: string): boolean {
        return this.serverTaskMailSent.has(taskId);
    }

    /**
     * 标记邮件已发送
     * @param taskId 任务ID
     */
    markMailAsSent(taskId: string): void {
        this.serverTaskMailSent.add(taskId);
    }

    /**
     * 清理过期缓存
     */
    async cleanupCache(): Promise<void> {
        const now = Date.now();
        for (const [playerId, cached] of this.playerTaskCache) {
            if (now - cached.timestamp > this.CACHE_TTL) {
                this.playerTaskCache.delete(playerId);
            }
        }
        this.log(`Task cache cleanup completed, remaining entries: ${this.playerTaskCache.size}`);
    }

    // ===== 私有辅助方法 =====

    /**
     * 转换玩家任务为Entity
     */
    private convertPlayerTasksToEntities(tasks: any[]): Task[] {
        return tasks.map(taskData => {
            return Task.create({
                id: taskData.taskId,
                name: taskData.name || taskData.taskId,
                description: taskData.description || '',
                type: taskData.type,
                status: taskData.status || TaskStatus.进行中,
                targets: taskData.targets || [],
                rewards: taskData.rewards || [],
                startTime: taskData.startTime || 0,
                endTime: taskData.endTime || 0,
                completedTime: taskData.completedTime,
                data: taskData
            });
        });
    }

    /**
     * 转换Entity为玩家任务数据
     */
    private convertEntitiesToPlayerTasks(tasks: Task[]): any[] {
        return tasks.map(task => ({
            taskId: task.id,
            name: task.name,
            description: task.description,
            type: task.type,
            status: task.status,
            targets: task.targets,
            rewards: task.rewards,
            startTime: task.startTime,
            endTime: (task as any).endTime,
            completedTime: (task as any).completedTime,
            ...task.data
        }));
    }

    /**
     * 转换全服任务为Entity
     */
    private convertServerTasksToEntities(tasks: any[]): Task[] {
        return tasks.map(taskData => Task.create({
            id: taskData.taskId,
            name: taskData.name || taskData.taskId,
            description: taskData.description || '',
            type: TaskType.SERVER,
            status: taskData.status || TaskStatus.进行中,
            targets: taskData.targets || [],
            rewards: taskData.rewards || [],
            data: taskData
        }));
    }

    /**
     * 转换Entity为全服任务数据
     */
    private convertEntitiesToServerTasks(tasks: Task[]): any[] {
        return tasks.map(task => ({
            taskId: task.id,
            name: task.name,
            description: task.description,
            status: task.status,
            targets: task.targets,
            rewards: task.rewards,
            ...task.data
        }));
    }

    /**
     * 转换世界任务为Entity
     */
    private convertWorldTasksToEntities(tasks: any[]): Task[] {
        return tasks.map(taskData => Task.create({
            id: taskData.taskId,
            name: taskData.name || taskData.taskId,
            description: taskData.description || '',
            type: TaskType.WORLD,
            status: taskData.status || TaskStatus.进行中,
            targets: taskData.targets || [],
            rewards: taskData.rewards || [],
            data: taskData
        }));
    }

    /**
     * 转换Entity为世界任务数据
     */
    private convertEntitiesToWorldTasks(tasks: Task[]): any[] {
        return tasks.map(task => ({
            taskId: task.id,
            name: task.name,
            description: task.description,
            status: task.status,
            targets: task.targets,
            rewards: task.rewards,
            ...task.data
        }));
    }

    /**
     * 从配置创建任务实体
     */
    private createTaskFromConfig(config: TaskConfig): Task {
        return Task.create({
            id: config.id,
            name: config.name,
            description: config.description,
            type: config.type,
            status: TaskStatus.进行中,
            targets: config.targets.map(target => ({ ...target, current: 0 })),
            rewards: config.rewards,
            startTime: config.startTime,
            endTime: config.endTime,
            data: config
        });
    }

    /**
     * 检查任务是否完成
     */
    private isTaskCompleted(task: Task): boolean {
        return task.targets.every(target => (target.current || 0) >= target.count);
    }

    /**
     * 计算任务奖励
     */
    private async calculateTaskRewards(task: Task): Promise<TaskReward[]> {
        // 这里可以根据任务类型、难度等因素计算动态奖励
        const rewards = task.rewards || [];
        return rewards.map(reward => ({
            ...reward,
            name: reward.name || `奖励_${reward.id}`,
            description: reward.description || `获得${reward.count}个${reward.name || reward.id}`
        }));
    }

    /**
     * 更新全服任务进度
     */
    private async updateServerTaskProgress(targetType: TaskTargetType, targetId: string | undefined, count: number): Promise<void> {
        // 这里需要实现全服任务进度更新逻辑
        // 暂时留空，等待具体需求
    }

    /**
     * 计算排行榜分数
     */
    private calculateRankingScore(taskData: PlayerTaskData, type: string): number {
        switch (type) {
            case 'completed_tasks':
                return taskData.totalCompletedTasks;
            case 'active_tasks':
                return taskData.playerTasks.filter(t => t.status === TaskStatus.进行中).length;
            default:
                return taskData.totalCompletedTasks;
        }
    }

    /**
     * 创建默认任务数据
     */
    private createDefaultTaskData(playerId: string): PlayerTaskData {
        return {
            playerId,
            playerTasks: [],
            serverTasks: [],
            worldTasks: [],
            completedTaskIds: [],
            totalCompletedTasks: 0,
            lastUpdateTime: Date.now(),
            lastUpdated: new Date()
        };
    }

    /**
     * 更新缓存
     */
    private updateCache(playerId: string, taskData: PlayerTaskData): void {
        this.playerTaskCache.set(playerId, {
            data: taskData,
            timestamp: Date.now()
        });
    }
}

// ===== 接口定义 =====

/**
 * 玩家任务数据接口
 */
export interface PlayerTaskData {
    playerId: string;
    playerTasks: Task[];
    serverTasks: Task[];
    worldTasks: Task[];
    completedTaskIds: string[];
    totalCompletedTasks: number;
    lastUpdateTime: number;
    lastUpdated: Date;
}

/**
 * 缓存数据接口
 */
interface CachedTaskData {
    data: PlayerTaskData;
    timestamp: number;
}

/**
 * 全服任务数据接口
 */
interface ServerTaskData {
    taskId: string;
    progress: number;
    totalRequired: number;
    lastUpdated: Date;
}

/**
 * 任务进度更新结果接口
 */
export interface TaskProgressUpdateResult {
    success: boolean;
    message: string;
    updatedTasks: Task[];
    completedTasks: Task[];
}

/**
 * 任务完成结果接口
 */
export interface TaskCompletionResult {
    success: boolean;
    message: string;
    task?: Task;
    rewards: TaskReward[];
}

/**
 * 全服任务统计接口
 */
export interface ServerTaskStats {
    totalPlayers: number;
    activePlayers: number;
    totalTasksCompleted: number;
    taskCompletionByType: Record<string, number>;
    averageTasksPerPlayer: number;
    lastUpdated: Date;
}

/**
 * 任务进度更新接口
 */
export interface TaskProgressUpdate {
    targetType: TaskTargetType;
    targetId?: string;
    count: number;
}

/**
 * 批量任务更新结果接口
 */
export interface BatchTaskUpdateResult {
    success: boolean;
    results: TaskProgressUpdateResult[];
    errors: { index: number; item: TaskProgressUpdate; error: string }[];
}
